package com.system.vote.admin.controller.app;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.system.vote.admin.entity.SysLoginLog;
import com.system.vote.admin.entity.TWxUserinfo;
import com.system.vote.admin.exception.BusinessException;
import com.system.vote.admin.security.JwtUtil;
import com.system.vote.admin.service.SysLoginLogService;
import com.system.vote.admin.service.TWxUserinfoService;
import com.system.vote.common.utils.IpUtils;
import com.system.vote.common.utils.StringUtils;
import com.system.vote.core.customBean.ResetPsdBean;
import com.system.vote.core.http.Result;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/app/vote/tWxUserinfo")
@Api(tags = "App前端用户信息")
@Slf4j
public class AppTUserInfoController {
    private final String MAIL = "MAIL";

    private int timeout = 5;
    @Value("${originPwd}")
    private String originPwd;

    @Autowired
    private TWxUserinfoService tWxUserinfoService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Value("${avatarImageFilePath}")
    private String avatarImageFilePath;

    @Autowired
    private SysLoginLogService sysLoginLogService;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;
    @Resource
    private JavaMailSender javaMailSender;

    public AppTUserInfoController() {
    }

    @GetMapping("/checkPhone")
    public Result checkPhone(@RequestParam String phone) {
        Map<String, Object> result = new HashMap<>();
        if (tWxUserinfoService.getByPhone(phone) == null) {
            result.put("isRegister", false);
            return Result.success(result);
        } else {
            return Result.error("手机号已经注册");
        }
    }

    @PostMapping("/checkEmail")
    public Result checkEmail(@RequestBody String email) {
        QueryWrapper<TWxUserinfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("email", email);
        TWxUserinfo tWxUserinfo = tWxUserinfoService.getOne(queryWrapper);
        Map<String, Object> result = new HashMap<>();
        if (tWxUserinfo == null) {
            result.put("isRegister", false);
            return Result.success(result);
        } else {
            return Result.error("邮箱已经注册");
        }
    }

    @PostMapping("/register")
    public Result register(@RequestBody TWxUserinfo tWxUserinfo) {
        if (tWxUserinfoService.getByPhone(tWxUserinfo.getPhone()) == null) {
            tWxUserinfo.setNickName(tWxUserinfo.getPhone());
            tWxUserinfo.setPassword(bCryptPasswordEncoder.encode(tWxUserinfo.getPassword()));
            tWxUserinfo.setRegisterDate(new Date());
            tWxUserinfo.setAvatarUrl("user.png");
            tWxUserinfo.setStatus("0");
            tWxUserinfoService.save(tWxUserinfo);
        } else {
            return Result.error("手机号已经注册");
        }
        Map<String, Object> result = new HashMap<>();
        result.put("isRegister", true);
        return Result.success(result);
    }

    @PostMapping("/updateBaseInfo")
    public Result save(@RequestBody TWxUserinfo tWxUserinfo) {
        if (tWxUserinfo.getId() > 0) {
            TWxUserinfo currentTWxUserinfo = tWxUserinfoService.getById(tWxUserinfo.getId());
            currentTWxUserinfo.setEmail(tWxUserinfo.getEmail());
            currentTWxUserinfo.setNickName(tWxUserinfo.getNickName());
            tWxUserinfoService.updateById(currentTWxUserinfo);
            return Result.success(tWxUserinfo);
        } else {
            return Result.error("参数错误");
        }
    }

    @PostMapping("/login")
    public Result login(HttpServletRequest request, @RequestBody TWxUserinfo tWxUserinfo) {

        if (StringUtils.isEmpty(tWxUserinfo.getCaptcha()) || StringUtils.isEmpty(tWxUserinfo.getUuid())) {
            throw new BusinessException("验证码不能为空");
        }
        if (!tWxUserinfo.getCaptcha().equals(redisTemplate.opsForValue().get(tWxUserinfo.getUuid()))) {
            throw new BusinessException("验证码错误");
        }
        TWxUserinfo currentUser = tWxUserinfoService.getPartiesTWxUserinfoByPhone(tWxUserinfo.getPhone());
        System.out.println("currentUser"+currentUser);
        if (currentUser == null) {
            throw new BusinessException("用户不存在");
        } else if (Objects.equals(currentUser.getStatus(), "1")) {
            throw new BusinessException("当前用户已经禁用，请联系管理员");
        } else {
            if (bCryptPasswordEncoder.matches(tWxUserinfo.getPassword(), currentUser.getPassword())) {

                //登录日志
                String ip = IpUtils.getIpAddr(request);
                String cityInfo = null;
                try {
                    cityInfo = IpUtils.getCityInfo(ip);
                } catch (Exception e) {
                    log.error("获取ip归属地信息失败！");
                }
                SysLoginLog sysLoginLog = new SysLoginLog();
                String userAgentStr = request.getHeader("User-Agent");
                sysLoginLog.setUserAgent(userAgentStr);
                UserAgent userAgent = UserAgentUtil.parse(userAgentStr);
                sysLoginLog.setDeviceName(userAgent.getOs().getName());
                sysLoginLog.setBrowserName(userAgent.getBrowser().getName());
                sysLoginLog.setType(2);
                sysLoginLog.setName(currentUser.getPhone());
                sysLoginLog.setUid(currentUser.getId());
                sysLoginLog.setIp(ip);
                sysLoginLog.setIpAttribution(cityInfo);
                sysLoginLog.setCreateTime(new Date());
                sysLoginLogService.save(sysLoginLog);

                currentUser.setLastLoginDate(new Date());
                tWxUserinfoService.updateById(currentUser);
                Map<String, Object> result = new HashMap<>();
                String token = JwtUtil.getJWTToken(String.valueOf(currentUser.getId()),tWxUserinfo.getPhone() );
                currentUser.setPassword("");
                result.put("token", token);
                result.put("currentUser", currentUser);
                return Result.success(result);
            } else {
                return Result.error("用户名或密码错误");
            }
        }
    }

    @PostMapping("/uploadImage")
    public Result uploadImage(MultipartFile file) throws Exception {
        Map<String, Object> dataMap = new HashMap<>();
        if (!file.isEmpty()) {
            String originalFileName = file.getOriginalFilename();
            String suffixName = null;
            if (originalFileName != null) {
                suffixName = originalFileName.substring(originalFileName.lastIndexOf("."));
            }
            String newFileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + "_" + UUID.randomUUID().toString() + suffixName;
            FileUtils.copyInputStreamToFile(file.getInputStream(), new File(avatarImageFilePath + newFileName));
            dataMap.put("fileName", newFileName);
            dataMap.put("src", "image/userAvatar/" + newFileName);
        }
        return Result.success("上传成功", dataMap);
    }

    @PostMapping("/updateAvatar")
    public Result updateAvatar(@RequestBody TWxUserinfo tWxUserinfo) {
        TWxUserinfo currentTWxUserinfo = tWxUserinfoService.getById(tWxUserinfo.getId());
        currentTWxUserinfo.setAvatarUrl(tWxUserinfo.getAvatarUrl());
        tWxUserinfoService.updateById(currentTWxUserinfo);
        return Result.success("更新头像成功", currentTWxUserinfo);
    }

    @GetMapping("/forgetPsd/byMail")
    public Result byMail(String phone) {
        QueryWrapper<TWxUserinfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("phone", phone);
        TWxUserinfo tWxUserinfo = tWxUserinfoService.getOne(queryWrapper);
        if (tWxUserinfo == null) {
            throw new BusinessException("手机号不存在");
        }
        String mail = tWxUserinfo.getEmail();
        if (mail == null) {
            throw new BusinessException("您的账号目前没有设置邮箱");
        }
        String verifyCode = String.valueOf(new Random().nextInt(9999));
        String key = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(key, verifyCode, 5, TimeUnit.MINUTES);
        // 编写邮箱内容
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<html><head><title></title></head><body>");
        stringBuilder.append("  您好<br/>");
        stringBuilder.append("  您的验证码是：").append(verifyCode).append("<br/>");
        stringBuilder.append("  您可以复制此验证码并返回系统找回密码页面，以验证您的邮箱。<br/>");
        stringBuilder.append("  此验证码只能使用一次，在");
        stringBuilder.append(timeout);
        stringBuilder.append("  分钟内有效。验证成功则自动失效。<br/>");
        stringBuilder.append("  如果您没有进行上述操作，请忽略此邮件。");
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        // 发件配置并发送邮件
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            //这里只是设置username 并没有设置host和password，因为host和password在springboot启动创建JavaMailSender实例的时候已经读取了
            mimeMessageHelper.setFrom("1917431122@qq.com");
            mimeMessageHelper.setTo(mail);
            mimeMessage.setSubject("邮箱验证-重置密码");
            mimeMessageHelper.setText(stringBuilder.toString(), true);
            javaMailSender.send(mimeMessage);
            System.out.println("email");
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        Map<String, Object> result = new HashMap<>();
        result.put("flag", true);
        result.put("UUID", key);
        return Result.success("发送成功", result);
    }

    @PostMapping("/resetPsdByMail")
    public Result resetPsdByMail(@RequestBody ResetPsdBean resetPsdBean) {

        if (StringUtils.isEmpty(resetPsdBean.getCode()) || StringUtils.isEmpty(resetPsdBean.getUuid())) {
            throw new BusinessException("验证码不能为空");
        } else if (!resetPsdBean.getCode().equals(redisTemplate.opsForValue().get(resetPsdBean.getUuid()))) {
            throw new BusinessException("验证码错误");
        }

        QueryWrapper<TWxUserinfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("phone", resetPsdBean.getPhone());
        TWxUserinfo tWxUserinfo = tWxUserinfoService.getOne(queryWrapper);
        if (tWxUserinfo == null) {
            throw new BusinessException("手机号不存在");
        } else if (Objects.equals(tWxUserinfo.getStatus(), "1")) {
            throw new BusinessException("当前用户已经禁用，请联系管理员");
        } else {
            tWxUserinfo.setPassword(bCryptPasswordEncoder.encode(resetPsdBean.getPassword()));
            tWxUserinfoService.updateById(tWxUserinfo);
            Map<String, Object> result = new HashMap<>();
            result.put("flag", true);
            redisTemplate.delete(resetPsdBean.getUuid());
            return Result.success("重置密码成功", result);
        }
    }

}
